import axios from 'axios'
import {ElLoading, ElMessage, ElNotification} from 'element-plus'
import {blobValidate} from "@/utils/common.js";
import errorCode from "@/utils/errorCode.js";
import {signBySHA256WithRSA} from "@/utils/cryptoUtils.js";
import {decryptByAES} from "@/utils/cryptoUtils.js";

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项，表示请求URL公共部分
  baseURL: '/api',
  // 超时
  timeout: 10000
})

// 请求拦截器
service.interceptors.request.use(config => {
  // 生成当前时间戳
  const timestamp = Date.now().toString();
  // 合并参数（URL参数和请求体参数）并过滤null值
  const mergedParams = { ...config.params, ...config.data };
  // console.log('mergedParams: ' + JSON.stringify(mergedParams));
  // 过滤值为null的参数
  const filteredParams = Object.entries(mergedParams)
    .filter(([_, value]) => value !== null && value !== undefined && value !== '')
    .reduce((obj, [key, value]) => {
      obj[key] = value;
      return obj;
    }, {});
  // 对参数进行排序
  const sortedParams = Object.keys(filteredParams).sort().reduce((obj, key) => {
    obj[key] = filteredParams[key];
    return obj;
  }, {});
  // 生成待签名字符串
  let signStr = '';
  // console.log('sortedParams: ' + JSON.stringify(sortedParams));
  // 如果sortedParams为空对象
  if(Object.keys(sortedParams).length === 0) {
    signStr = `timestamp=${timestamp}`;
  } else {
    signStr = Object.entries(sortedParams)
    .map(([k, v]) => `${k}=${v === '' ? '' : v}`)
    .join('&') + `&timestamp=${timestamp}`;
  }
  // console.log('signStr: ' + signStr);
  const rawKey = import.meta.env.VITE_RSA_SIGN_PRIVATE_KEY
  // 使用PKCS#8格式的PEM头
  const privateKey = `-----BEGIN PRIVATE KEY-----
${rawKey}
-----END PRIVATE KEY-----`;
  const signValue = signBySHA256WithRSA(privateKey, signStr);
  config.headers.timestamp = timestamp;
  config.headers.sign = signValue;
  return config;
}, error => {
  return Promise.reject(error);
})

// 响应拦截器
service.interceptors.response.use(res => {
    // console.log(res);
    // 未设置状态码则默认成功状态
    const code = res.data.code || 200;
    // 获取错误信息
    const msg = res.data.msg
    // 二进制数据则直接返回
    if (res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer') {
      return res.data
    }
    if (code !== 200) {
        ElNotification({
            title: 'Error',
            message: msg,
            type: 'error',
        })
      return Promise.reject('error')
    } else {
      // 判断res.data.encrypt是否为1 如果是则进行解密
      if(res.data.encrypt && res.data.encrypt === 1) {
        if(res.data.data) {
          res.data.data = decryptByAES(res.data.data);
        }
        if(res.data.msg) {
          res.data.msg = decryptByAES(res.data.msg);
        }
      }
      return res.data
    }
  },
  error => {
    console.log('err' + error)
    let { message } = error;
    ElMessage.error(message)
    return Promise.reject(error)
  }
)

// 通用下载方法
let downloadLoadingInstance;
export function download(url, filename, data) {
    downloadLoadingInstance = ElLoading.service({ text: "正在下载数据，请稍候", background: "rgba(0, 0, 0, 0.7)", })
    return service.post(url, { ...data },{responseType: 'blob'})
        .then(async (data) => {
        const isBlob = blobValidate(data);
        console.log("isBlob: " + isBlob)
        if (isBlob) {
            const blob = new Blob([data])
            saveAs(blob, filename)
        } else {
            const resText = await data.text();
            const rspObj = JSON.parse(resText);
            const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
            ElMessage.error(errMsg);
        }
        downloadLoadingInstance.close();
    }).catch((r) => {
        console.error(r)
        ElMessage.error('下载文件出现错误，请联系管理员！')
        downloadLoadingInstance.close();
    })
}

export default service
